home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
-
- FICHERO: IMG.C
-
- AUTOR: ANTONIO LADESA JURADO
-
- FECHA: 24/6/94
-
- DESCRIPCION:
-
- Fichero que contiene las estructuras, constantes, variables y funciones
- internas y externas para el procesamiento de ficheros IMG.
-
- ==============================================================================*/
-
-
- /*---- MODULOS USADOS --------------------------------------------------------*/
-
- #include <stdio.h>
- #include <alloc.h>
- #include <string.h>
- #include <stdlib.h>
-
- #include "global.h"
- #include "memoria.h"
- #include "video.h"
- #include "img.h"
- #include "error.h"
-
- /*---- ESTRUCTURAS, CONSTANTES Y VARIABLES LOCALES AL MODULO -----------------*/
-
-
- typedef struct
- {
- int id1;
- int id2;
- int planos;
- int longitud;
- int ancho_pixels;
- int alto_pixels;
- int ancho_linea;
- int alto_imagen;
- }
- CABimg;
-
- /* longitud del patron de lectura */
- static int long_patron;
- /* lineas a repetir */
- static int lineas;
-
-
- /*---- DEFINICION DE LAS FUNCIONES INTERNAS ----------------------------------*/
-
-
- IMAGEN *IMGleerCabecera(IMAGEN *c,FILE *f,char *nombre);
- IMAGEN *IMGleerImagen(IMAGEN *c,FILE *);
- int IMGleerLinea(char *,FILE *,int);
-
- char *IMGcrearCabecera(IMAGEN *c,char *cabaux);
- int IMGescribirLinea(char *p,FILE *f,int bytes);
- int IMGescribirImagen(IMAGEN *c,FILE *f);
-
- /*---- CODIFICACION DE LAS FUNCIONES OFRECIDAS -------------------------------*/
-
-
- /*---- FUNCION: extern IMAGEN *IMGcargar(char *nombre,IMAGEN *c) ---------------
-
- Descripción:
-
- Esta función carga en memoria una imagen de tipo IMG.
-
- Parámetros:
-
- char *nombre : nombre del fichero a cargar
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- extern IMAGEN *IMGcargar(char *nombre,IMAGEN *c)
- {
- /* puntero al fichero */
- FILE *f;
-
- /* abrir el fichero */
- if((f = fopen(nombre, "rb")) != NULL)
- {
- /* leer cabecera IMG */
- if((c = IMGleerCabecera(c,f,nombre))!=NULL)
- /* leer imagen */
- c = IMGleerImagen(c,f);
- fclose(f);
- }
- else
- {
- ERRORponer(ERRapertura);
- return(NULL);
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: extern int *IMGsalvar(char *nombre,IMAGEN *c) ------------------
-
- Descripción:
-
- Esta función salva en disco una imagen con formato IMG.
-
- Parámetros:
-
- char *nombre : nombre del fichero a salvar
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- Retorno:
-
- - 0 si hay error
- - 1 en caso contrario
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- /* salvar un fichero IMG */
- extern int IMGsalvar(char *nombre,IMAGEN *c)
- {
- /* array auxiliar */
- char cabaux[16];
- /* puntero al fichero */
- FILE *f;
- /* cabecera del fichero IMG */
- CABimg cabecera;
-
- /* abrir el fichero */
- if((f = fopen(nombre, "wb")) == NULL)
- {
- ERRORponer(ERRapertura);
- return(0);
- }
-
- /* adecuar el modo de vídeo a la imagen */
- if(c->modo == VIDEOvga)
- c=VIDEOvision(c);
-
- /* crear la cabecera IMG */
- memcpy((char *)&cabecera,IMGcrearCabecera(c,cabaux),16);
- /* escribir la cabecera IMG */
- if(fwrite((char *)&cabecera,1,sizeof(cabecera),f) != sizeof(cabecera))
- {
- ERRORponer(ERRescritura);
- return(0);
- }
- /* escribir la imagen IMG */
- IMGescribirImagen(c,f);
- fclose(f);
- return(1);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- CODIFICACION DE LAS FUNCIONES INTERNAS --------------------------------*/
-
-
- /*---- FUNCION: IMAGEN *IMGleerCabecera(IMAGEN *c,FILE *f,char *nombre) --------
-
- Descripción:
-
- Esta función reserva memoria para la imagen y lee la cabecera del fichero
- IMG.
-
- Parámetros:
-
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
- char *nombre : nombre del fichero a cargar
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- IMAGEN *IMGleerCabecera(IMAGEN *c,FILE *f,char *nombre)
- {
- /* array auxiliar */
- char cabaux[16];
- /* cabecera del fichero IMG */
- CABimg cabecera;
-
- /* leer cabecera IMG */
- if(fread((char *)&cabaux,1,sizeof(cabecera),f) == sizeof(cabecera))
- {
- /* comprobar que es IMG */
- if(memcmp("\x00\x01\x00\x08",cabaux,4))
- {
- ERRORponer(ERRnoTratado);
- return(NULL);
- }
- }
- else
- {
- ERRORponer(ERRlectura);
- return(NULL);
- }
- /* los enteros vienen en formato MOTOROLA, cambiarlos */
- swab(cabaux,(char *)&cabecera,16);
-
- /* reservar memoria para la cabecera de trabajo */
- if((c=MEMreservarCAB(c))==NULL)
- {
- ERRORponer(ERRnoMemoria);
- return(NULL);
- }
- /* cargar cabecera de trabajo */
- strcpy(c->nombre,nombre);
- c->ancho = cabecera.ancho_linea;
- c->alto = cabecera.alto_imagen;
- c->formato = IMG;
- c->haypaleta = FALSO;
- /* determinar tipo de imagen */
- switch(cabecera.planos)
- {
- /* monocromática */
- case 1:
- c->modo = VIDEOmono;
- c->colores = 2;
- c->bytes = DePixelsABytes(c->ancho);
- break;
-
- /* 16 grises */
- case 4:
- c->modo = VIDEOega;
- c->colores = 16;
- c->bytes = DePixelsABytes(c->ancho) * 4;
- break;
- /* 256 grises */
- case 8:
- c->modo = VIDEOvga;
- c->colores = 256;
- c->bytes = c->ancho;
- break;
-
- default:
- /* formato desconocido */
- ERRORponer(ERRnoTratado);
- c = MEMliberar(c);
- return(c);
- }
- /* patron de lectura */
- long_patron = cabecera.longitud;
-
- /* si no hay memoria para la imagen, liberar cabecera */
- if(!MEMreservar(c))
- {
- c =MEMliberar(c);
- ERRORponer(ERRnoMemoria);
- return(c);
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: IMAGEN *IMGleerImagen(IMAGEN *c,FILE *f) -----------------------
-
- Descripción:
-
- Esta función carga en memoria una imagen de tipo IMG.
-
- Parámetros:
-
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
-
- Retorno:
-
- Puntero a la estructura de la imagen
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- IMAGEN *IMGleerImagen(IMAGEN *c,FILE *f)
- {
- /* contador de líneas */
- int i;
- /* buffers de lectura */
- char p[ANCHO_MAXIMO];
- char q[ANCHO_MAXIMO];
-
- lineas = 1;
- /* cargar imagen */
- for(i = 0; i < c->alto ;)
- {
- if(c->modo == VIDEOvga)
- {
- IMGleerLinea(q,f,c->bytes);
- /* la imagen viene codificada por planos */
- VGAdePlanoaPixel(q,p,c->ancho);
- }
- else
- IMGleerLinea(p,f,c->bytes);
- /* llevar a memoria la(s) línea(s) */
- while(lineas--)
- {
- MEMescribir(p,i,c);
- ++i;
- }
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void IMGleerLinea(char *p, FILE *f,int bytes) ------------------
-
- Descripción:
-
- Esta función lee una línea de un fichero IMG.
-
- Parámetros:
-
- char *p : puntero a buffer donde se almacena la línea
- FILE *f : puntero al fichero
- int bytes: numero de bytes por linea
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- int IMGleerLinea(char *p,FILE *f,int bytes)
- {
- /* puntero a la primera posición libre */
- char *pr;
- /* contadores */
- int j,k,n=0,i;
- /* byte a tratar */
- int c;
-
- memset(p,0,bytes);
- lineas = 1;
-
- do
- {
- /* leer byte */
- c = fgetc(f) & 0xff;
- /* si es cero... */
- if(c==0)
- {
- /* leer siguiente */
- c=fgetc(f) & 0xff;
- /* si es cero, se trata de una línea repetida */
- if(c==0)
- {
- /* leer 0xff */
- fgetc(f);
- /* guardar numero de líneas */
- lineas = fgetc(f) & 0xff;
- }
- else
- {
- /* si no es cero, es un 'pattern run' */
- /* leer numero de repeticiones del patrón */
- i=c & 0xff;
- /* buffer de repetición */
- pr=p+n;
- /* leer del fichero el patrón a repetir */
- j=long_patron;
- while(j--)
- p[n++]=~fgetc(f);
- /* repetir el patrón */
- k=i-1;
- while(k--)
- {
- memcpy(p+n,pr,long_patron);
- n+=long_patron;
- }
- }
- }
- else
- /* si vale 0x80, es un 'bit string' */
- if(c==0x80)
- {
- i=fgetc(f) & 0xff;
- /* leer contador */
- pr=p+n;
- j=i;
- /* leer los bytes del fichero */
- while(j--)
- p[n++]=~fgetc(f);
- }
- else
- /* leer bytes de color negro */
- if(c & 0x80)
- {
- /* determinar numero de bytes */
- i = c & 0x7f;
- pr = p+n;
- j=i;
- /* repetirlos */
- while(j--)
- p[n++]=~0xff;
- }
- else
- /* leer bytes de color blanco */
- {
- /* determinar numero de bytes */
- i=c &0x7f;
- pr =p+n;
- j=i;
- /* repetirlos */
- while(j--)
- p[n++]=~0x00;
- }
- }
- while(n < bytes);
- return(n);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void IMGcrearCabecera(IMAGEN *c) -------------------------------
-
- Descripción:
-
- Esta función crea una cabecera IMG.
-
- Parámetros:
-
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- char *IMGcrearCabecera(IMAGEN *c,char *cabaux)
- {
- memcpy(cabaux,"\x00\x01\x00\x08\x00\x01\x00\x01\x00\x55\x00\x55",12);
- cabaux[13] = c->ancho & 0xff;
- cabaux[12] = (c->ancho & 0xff00) >> 8;
- cabaux[15] = c->alto & 0xff;
- cabaux[14] = (c->alto & 0xff00) >> 8;
-
- switch(c->modo)
- {
- case VIDEOmono:cabaux[5] = 1;break;
- case VIDEOega: cabaux[5] = 4;break;
- case VIDEOvga: cabaux[5] = 8;break;
- }
- return(cabaux);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void IMGescribirImagen(IMAGEN *c,FILE *f) ----------------------
-
- Descripción:
-
- Esta función graba la imagen en un fichero IMG.
-
- Parámetros:
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- int IMGescribirImagen(IMAGEN *c,FILE *f)
- {
- int i;
- char p[ANCHO_MAXIMO];
- char q[ANCHO_MAXIMO];
-
- /* salvar imagen */
- for(i = 0; i < c->alto;i++)
- {
- if(c->modo == VIDEOvga)
- {
- MEMleer(q,i,c);
- /* codificar por plano */
- VGAdePixelaPlano(q,p,c->ancho);
- }
- else
- MEMleer(p,i,c);
- IMGescribirLinea(p,f,c->bytes);
- }
- return(1);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void IMGescribirLinea(char *p, FILE *f,int bytes) --------------
-
- Descripción:
-
- Esta función escribe una línea en un fichero IMG.
-
- Parámetros:
-
- char *p : puntero a buffer que alberga la línea
- FILE *f : puntero al fichero
- int bytes : numero de bytes por línea
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- int IMGescribirLinea(char *p,FILE *f,int bytes)
- {
- int bdex=0,i=0,j=0,t=0;
- char b[ANCHO_MAXIMO];
- do
- {
- i=0;
- while((p[t+i]==p[t+i+1]) && ((t+i) < (bytes-1)) && i < 0x7e)
- ++i;
- if(i>0 || bdex >= 0x7e)
- {
- if(bdex)
- {
- /* bit string */
- fputc(0x80,f);
- fputc(bdex,f);
- j+=2;
- fwrite(b,1,bdex,f);
- j+=bdex;
- bdex=0;
- }
- if(i)
- {
- /* byte blanco */
- if(p[t+i]==0xff)
- {
- fputc(i+1,f);
- j++;
- }
- else
- /* byte negro */
- if(p[t+i]==0x00)
- {
- fputc(i+1+0x80,f);
- j++;
- }
- else
- {
- /* pattern run */
- fputc(0x00,f);
- fputc(i+1,f);
- fputc(~p[t+i],f);
- j+=3;
- }
- t+=(i+1);
- }
- }
- else
- b[bdex++]=~p[t++];
- }while(t<bytes);
-
- /* bit string pendiente */
- if(bdex)
- {
- fputc(0x80,f);
- fputc(bdex,f);
- j+=2;
- fwrite(b,1,bdex,f);
- j+=bdex;
- }
- return(bytes);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/